﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace DesktopShare
{
    public delegate void DataReceiveDelegate(byte[] data);
    public class BroadcastSocket
    {
        public BroadcastSocket(IPAddress broadcastAddress, int port)
        {
            BroadcastAddress = broadcastAddress;
            Port = port;
            TempData = new List<byte[]>();
            Key = broadcastAddress.ToString();
            IP = Desktop.GetIPAddress();
        }
        public IPAddress IP { get; set; }
        public int Port { get; set; }
        public string Key { get; set; }
        public Socket UdpReceive { get; set; }
        public IPAddress BroadcastAddress { get; set; }
        public event DataReceiveDelegate OnDataReceive;
        private bool IsReceive = true;
        private List<byte[]> TempData;
        private Thread ReceiveThread;

        public void Run()
        {
            if (UdpReceive == null)
            {
                IPEndPoint ipe = new IPEndPoint(IP, Port);
                UdpReceive = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                UdpReceive.ReceiveBufferSize = 1024 * 1024 * 5;
                UdpReceive.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(BroadcastAddress));
                UdpReceive.Bind(ipe);
                ReceiveThread = new Thread(new ThreadStart(ListenThread));
                ReceiveThread.IsBackground = true;
                ReceiveThread.Start();
            }
        }

        public void Stop()
        {
            IsReceive = false;
            if (UdpReceive != null)
            {
                OnDataReceive = null;
                UdpReceive.Close();
                UdpReceive = null;
            }
        }

        private void ListenThread()
        {
            try
            {
                while (IsReceive)
                {
                    byte[] receive = new byte[1401];
                    int count = UdpReceive.Receive(receive);
                    if (receive[0] == 1)
                    {
                        if (receive[1] == 0x0C)
                        {
                            TempData.Add(receive.Take(count).ToArray());
                            var res = RTP.GetFullData(TempData);
                            OnDataReceive?.Invoke(res);
                            TempData.Clear();
                        }
                        else
                        {
                            TempData.Add(receive);
                        }
                    }
                    else if (receive[0] == 3)
                    {

                    }
                    else if (receive[0] == 2)
                    {
                        if (receive[1] == 0x0E)
                        {
                            var commond = RTP.GetCommond(receive);
                            switch (commond)
                            {
                                case "JOIN": break;
                                case "END": break;
                                default: break;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                TempData.Clear();
            }
        }
    }

}
